#ifndef __IAM_RASTERDATA_H__
#define __IAM_RASTERDATA_H__

#include "iam_rasterview.h"

/**
 * @brief Float32 栅格数据对象
 * 
 */
typedef struct _IAM_RasterData_F32_
{
    IAM_RasterView_F32 m_view; // 栅格视角对象
    float* m_p_raw_data;         // 数据指针, 需要负责创建和释放
} _IAM_RasterData_F32;
typedef _IAM_RasterData_F32* IAM_RasterData_F32;

/* 初始化 Float32 栅格数据对象 */
IAM_RasterData_F32 IAM_RasterData_init0_F32(void);
IAM_RasterData_F32 IAM_RasterData_init_F32(size_t size_x, size_t size_y);

/* 重新设置 Float32 栅格数据对象的大小 */
void IAM_RasterData_reset_F32(IAM_RasterData_F32 data, size_t size_x, size_t size_y);

/* 释放 Float32 栅格数据对象 */
void IAM_RasterData_release_F32(IAM_RasterData_F32* p_data);

/* 获取栅格数据对象在坐标(xid, yid)处的值 */
float IAM_RasterData_getValue_F32(const IAM_RasterData_F32 data, size_t xid, size_t yid);

/* 设置栅格数据对象在坐标(xid, yid)处的值 */
void IAM_RasterData_setValue_F32(IAM_RasterData_F32 data, size_t xid, size_t yid, float value);

/* 判读value是否为无效数据 */
bool IAM_RasterData_isNodata_F32(const IAM_RasterData_F32 data, float value);

/**
 * @brief Float64 栅格数据对象
 * 
 */
typedef struct _IAM_RasterData_F64_
{
    IAM_RasterView_F64 m_view; // 栅格视角对象
    double* m_p_raw_data;         // 数据指针, 需要负责创建和释放
} _IAM_RasterData_F64;
typedef _IAM_RasterData_F64* IAM_RasterData_F64;

/* 初始化 Float64 栅格数据对象 */
IAM_RasterData_F64 IAM_RasterData_init0_F64(void);
IAM_RasterData_F64 IAM_RasterData_init_F64(size_t size_x, size_t size_y);

/* 重新设置 Float64 栅格数据对象的大小 */
void IAM_RasterData_reset_F64(IAM_RasterData_F64 data, size_t size_x, size_t size_y);

/* 释放 Float64 栅格数据对象 */
void IAM_RasterData_release_F64(IAM_RasterData_F64* p_data);

/* 获取栅格数据对象在坐标(xid, yid)处的值 */
double IAM_RasterData_getValue_F64(const IAM_RasterData_F64 data, size_t xid, size_t yid);

/* 设置栅格数据对象在坐标(xid, yid)处的值 */
void IAM_RasterData_setValue_F64(IAM_RasterData_F64 data, size_t xid, size_t yid, double value);

/* 判读value是否为无效数据 */
bool IAM_RasterData_isNodata_F64(const IAM_RasterData_F64 data, double value);

/**
 * @brief CFloat32 栅格数据对象
 * 
 */
typedef struct _IAM_RasterData_CF32_
{
    IAM_RasterView_CF32 m_view; // 栅格视角对象
    CpxFloat* m_p_raw_data;         // 数据指针, 需要负责创建和释放
} _IAM_RasterData_CF32;
typedef _IAM_RasterData_CF32* IAM_RasterData_CF32;

/* 初始化 CFloat32 栅格数据对象 */
IAM_RasterData_CF32 IAM_RasterData_init0_CF32(void);
IAM_RasterData_CF32 IAM_RasterData_init_CF32(size_t size_x, size_t size_y);

/* 重新设置 CFloat32 栅格数据对象的大小 */
void IAM_RasterData_reset_CF32(IAM_RasterData_CF32 data, size_t size_x, size_t size_y);

/* 释放 CFloat32 栅格数据对象 */
void IAM_RasterData_release_CF32(IAM_RasterData_CF32* p_data);

/* 获取栅格数据对象在坐标(xid, yid)处的值 */
CpxFloat IAM_RasterData_getValue_CF32(const IAM_RasterData_CF32 data, size_t xid, size_t yid);

/* 设置栅格数据对象在坐标(xid, yid)处的值 */
void IAM_RasterData_setValue_CF32(IAM_RasterData_CF32 data, size_t xid, size_t yid, CpxFloat value);

/* 判读value是否为无效数据 */
bool IAM_RasterData_isNodata_CF32(const IAM_RasterData_CF32 data, CpxFloat value);

/**
 * @brief CFloat64 栅格数据对象
 * 
 */
typedef struct _IAM_RasterData_CF64_
{
    IAM_RasterView_CF64 m_view; // 栅格视角对象
    CpxDouble* m_p_raw_data;         // 数据指针, 需要负责创建和释放
} _IAM_RasterData_CF64;
typedef _IAM_RasterData_CF64* IAM_RasterData_CF64;

/* 初始化 Float32 栅格数据对象 */
IAM_RasterData_CF64 IAM_RasterData_init0_CF64(void);
IAM_RasterData_CF64 IAM_RasterData_init_CF64(size_t size_x, size_t size_y);

/* 重新设置 Float32 栅格数据对象的大小 */
void IAM_RasterData_reset_CF64(IAM_RasterData_CF64 data, size_t size_x, size_t size_y);

/* 释放 Float32 栅格数据对象 */
void IAM_RasterData_release_CF64(IAM_RasterData_CF64* p_data);

/* 获取栅格数据对象在坐标(xid, yid)处的值 */
CpxDouble IAM_RasterData_getValue_CF64(const IAM_RasterData_CF64 data, size_t xid, size_t yid);

/* 设置栅格数据对象在坐标(xid, yid)处的值 */
void IAM_RasterData_setValue_CF64(IAM_RasterData_CF64 data, size_t xid, size_t yid, CpxDouble value);

/* 判读value是否为无效数据 */
bool IAM_RasterData_isNodata_CF64(const IAM_RasterData_CF64 data, CpxDouble value);

typedef enum {
    IAM_RasterData_PadModel_fill,      // 固定值 
    IAM_RasterData_PadModel_symmetric, // 图像大小通过围绕边界进行镜像反射来扩展
    IAM_RasterData_PadModel_replicate, // 图像大小通过复制外边界中的值来扩展
    IAM_RasterData_PadModel_circular,  // 通过将图像看成是一个二维周期函数的一个周期来进行扩展
} IAM_RasterData_PadModel;

typedef enum {
    IAM_RasterData_Direction_pre,  // 在每一维的第一个元素前填充
    IAM_RasterData_Direction_post, // 在每一维的最后一个元素后填充   
    IAM_RasterData_Direction_both, // 在每一维的第一个元素前和最后一个元素后填充
} IAM_RasterData_Direction;

/**
 * @brief 填充栅格数据, 类似 matlab 的 padarray
 * 
 * @param src_data 输入栅格
 * @param pad_model 填充模式, 见 IAM_RasterData_PadModel
 * @param pad_direction 填充方向, 见 IAM_RasterData_Direction
 * @param pad_radius_x x方向填充半径
 * @param pad_radius_y y方向填充半径
 * @param fill_value 填充值, 当pad_model=IAM_RasterData_PadModel_fill时有效
 * @param dst_data 输出栅格
 */
void IAM_RasterData_padarray_F32(const IAM_RasterView_F32 src_data
    , IAM_RasterData_PadModel pad_model
    , IAM_RasterData_Direction pad_direction
    , int pad_radius_x, int pad_radius_y
    , float fill_value
    , IAM_RasterData_F32 dst_data);

void IAM_RasterData_padarray_F64(const IAM_RasterView_F64 src_data
    , IAM_RasterData_PadModel pad_model
    , IAM_RasterData_Direction pad_direction
    , int pad_radius_x, int pad_radius_y
    , float fill_value
    , IAM_RasterData_F64 dst_data);

#endif
